<!--
 * @Author: Aaron
 * @Date: 2021-08-26 11:52:15
 * @LastEditors: YanMeng
 * @LastEditTime: 2022-10-28 10:31:42
 * @Description: file content
 * @FilePath: \ias_ui\src\components\eTable\eTable.vue
 * @Company: 沃尔玛
-->
<template>
  <div :id="identifiers" class="table-pagination">
    <div class="table-header">
      <div><slot name="left" /></div>
      <div><slot name="right" /></div>
    </div>
    <el-table
      ref="elTableRef"
      :key="tableKey"
      :size="size"
      class="table"
      border
      :empty-text="emptyText"
      :data="dataList"
      style="width: 100%"
      :height="tableHeight ? tableHeight : null"
      :row-key="getRowKeys"
      :span-method="spanMethod"
      @selection-change="selectionChange"
    >
      <el-table-column
        v-for="(val, i) in theadList"
        :key="i"
        show-overflow-tooltip
        :label="val.required ? `*${val.name}` : val.name"
        :min-width="val.minWidth || 80"
        :width="val.width || ''"
        :align="val.align ? val.align : 'center'"
        :prop="val.value"
        :type="val.type ? val.type : ''"
        :selectable="selectable"
        :fixed="val.fixed ? val.fixed : false"
        :reserve-selection="true"
      >
        <template v-if="val.slot || val.btnList || val.type === 'expand'" v-slot="scope">
          <slot v-if="val.slot" :name="val.slot" :scope="scope" :parameter="val" />
          <div v-else-if="val.btnList && val.btnList.length !== 0" class="btn">
            <div v-for="element in btnShow(val.btnList, scope.row)" :key="element.on">
              <el-button
                :type="element.type || 'text'"
                size="mini"
                @click="
                  $emit(element.on, scope, element)
                  $emit('tableEvent', scope, element)
                "
              >
                {{ element.text }}
              </el-button>
            </div>
          </div>
        </template>
      </el-table-column>
    </el-table>
    <div v-if="paginationShow" class="pagination">
      <el-pagination
        :current-page.sync="pageParams.pageNum"
        :page-sizes="pageSizeList"
        :page-size="pageSizeList[0]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>

<script>
export default {
  name: 'Table',
  props: {
    // 表格表头
    theadList: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 表单表格数据
    dataList: {
      type: Array,
      default: () => {
        return []
      }
    },
    total: {
      type: Number,
      default: 0
    },
    size: {
      type: String,
      default: 'small'
    },
    externalHeight: {
      type: Number,
      default: 0
    },
    paginationShow: {
      type: Boolean,
      default: true
    },
    countHeight: {
      // 是否开启计算高度
      type: Boolean,
      default: true
    },
    emptyText: {
      type: String,
      default: '暂无数据'
    },
    pageNum: {
      type: Number,
      default: 1
    },
    rowKey: {
      type: String,
      default: 'id'
    },
    pageSizeList: {
      type: Array,
      default() {
        return [10, 50, 100, 500]
      }
    },
    pageParams: {
      type: Object,
      default() {
        return {
          pageNum: 1,
          pageSize: this.pageSizeList[0]
        }
      }
    },
    selectable: {
      type: Function,
      default() {
        return () => {
          return true
        }
      }
    },
    spanMethod: {
      type: Function,
      default() {
        return () => {
          return {
            rowspan: 0,
            colspan: 0
          }
        }
      }
    },
    containerBox: {
      type: String,
      default: '.app-main'
    },
    otherContainerBox: {
      // 容器里面需要减去的高度的组件。值为类名或者id，页面内不能有一样的
      type: Array,
      default() {
        return []
      }
    },
    resizeObserverEle: {
      type: Array,
      default() {
        return []
      }
    }
  },
  data() {
    return {
      tableKey: 0,
      tableHeight: 0,
      contentHeight: 0,
      identifiers: `_${parseInt(Math.random() * (10000 - 0 + 1) + 0, 10)}`,
      isKeepAlive: false,
      resizeObserverObj: null
    }
  },
  watch: {
    pageNum(v) {
      this.pageParams.pageNum = v
    }
  },
  mounted() {
    if (this.countHeight) {
      this.createAutoSetHeight()
    }
  },
  activated() {
    if (this.isKeepAlive && this.countHeight) {
      this.createAutoSetHeight()
    }
  },
  deactivated() {
    this.isKeepAlive = true
    if (this.countHeight) this.closeAutoSetHeight()
  },
  beforeDestroy() {
    if (this.countHeight) this.closeAutoSetHeight()
  },
  methods: {
    clearSelection() {
      this.$refs.elTableRef.clearSelection()
    },
    getRowKeys(row) {
      return row[this.rowKey]
    },
    btnShow(list, data) {
      return list.filter((item) => {
        let flag = true
        if (item.choose) {
          if (item.choose.value && Array.isArray(item.choose.value)) {
            // debugger
            item.choose.value.forEach((e) => {
              if (!item.choose[e]) return
              const index = item.choose[e].indexOf(data[e])
              if (index === -1 && !item.choose.isShowButtonLiu) flag = false
              if (index !== -1 && item.choose.isShowButtonLiu) flag = false
            })
          }
          if (flag && item.choose.range && Array.isArray(item.choose.range) && !item.choose.isShow) {
            item.choose.range.forEach((e) => {
              const minKey = `${e}Min`
              const maxKey = `${e}Max`
              if (item.choose[minKey] && data[e] - 0 < item.choose[minKey] - 0) flag = false
              if (item.choose[maxKey] && data[e] - 0 > item.choose[maxKey] - 0) flag = false
            })
          }
          if (flag && item.choose.range && Array.isArray(item.choose.range) && item.choose.isShow) {
            item.choose.range.forEach((e) => {
              const minKey = `${e}Min` // statusMin
              const maxKey = `${e}Max` // statusMax
              if (item.choose[minKey]) {
                if (Array.isArray(item.choose[minKey])) {
                  if (item.choose[minKey].indexOf(data[e]) === -1) {
                    flag = false
                  }
                } else {
                  if (Number(item.choose[minKey]) !== Number(data[e])) {
                    flag = false
                  }
                }
              }
              if (item.choose[maxKey]) {
                if (Array.isArray(item.choose[maxKey])) {
                  if (item.choose[maxKey].indexOf(data[e]) === -1) {
                    flag = false
                  }
                } else {
                  if (Number(item.choose[maxKey]) !== Number(data[e])) {
                    flag = false
                  }
                }
              }
            })
          }
        }
        return flag
      })
    },
    handleSizeChange(val) {
      this.$emit('handleSizeChange', val)
      this.pageParams.pageSize = val
      this.pageParams.pageNum = 1
      this.$emit('handlePageChange', { pageNum: this.pageParams.pageNum, pageSize: this.pageParams.pageSize })
    },
    handleCurrentChange(val) {
      this.pageParams.pageNum = val
      this.$emit('handleCurrentChange', this.pageParams.pageNum)
      this.$emit('handlePageChange', { pageNum: this.pageParams.pageNum, pageSize: this.pageParams.pageSize })
    },
    // 选中数据发生改变时候
    selectionChange(val) {
      this.$emit('selectionChange', val)
    },
    setHeight() {
      try {
        this.$nextTick(() => {
          this.contentHeight = document.querySelector(this.containerBox).offsetHeight
          if (!this.contentHeight) return
          const essTable = document.querySelector('#' + this.identifiers)
          const tableGHeaderHeight = essTable.querySelector('.table-header').offsetHeight // 列表的头部
          const otherContainerBoxHeight = this.otherContainerBox.reduce((item, next) => {
            const e = document.querySelector(next)
            if (e) item += e.offsetHeight
            return item
          }, 0)
          const paginationHeight = essTable.querySelector('.pagination') ? essTable.querySelector('.pagination').offsetHeight + 20 : 0
          this.tableHeight = this.contentHeight - this.externalHeight - otherContainerBoxHeight - tableGHeaderHeight - paginationHeight
        })
        // eslint-disable-next-line no-empty
      } catch (error) {}
    },
    resizeObserverFun() {
      this.resizeObserverObj = new ResizeObserver(this.setHeight)
      this.resizeObserverEle.forEach((_) => {
        const e = document.querySelector(_)
        console.log(e)
        if (e) this.resizeObserverObj.observe(e)
      })
    },
    createAutoSetHeight() {
      this.setHeight()
      if (Array.isArray(this.resizeObserverEle) && this.resizeObserverEle.length) this.resizeObserverFun()
      else window.addEventListener('resize', this.setHeight)
    },
    closeAutoSetHeight() {
      if (Array.isArray(this.resizeObserverEle) && this.resizeObserverEle.length) this.resizeObserverObj.disconnect()
      else window.removeEventListener('resize', this.setHeight)
    }
  }
}
</script>
<style scoped lang="scss">
.cursor {
  cursor: pointer;
}
.table-pagination {
  padding: 0 20px;
  .table-header {
    display: flex;
    justify-content: space-between;
    /deep/ .el-button {
      margin: 0;
    }
    & > div {
      display: flex;
      align-items: center;
    }
  }
  .pagination {
    display: flex;
    justify-content: flex-end;
    margin-top: 10px;
  }
}
.btn {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  & > div {
    padding-right: 2px;
  }
}
</style>
